/**
 * @file system.c
 * @author liangwenhao (1943080020@qq.com)
 * @brief 
 * @version 0.1
 * @date 2021-07-27
 * 
 * @copyright Copyright (c) 2021
 * 
 * @authorGitee  https://gitee.com/liangwenhao
 * @authorGithub https://github.com/WHaoL
 * @authorBlogs https://blog.csdn.net/liangwenhao1108
 *  
 * @Code Description: P212-213  模拟system()函数，调用system函数
 *              system()函数内部是  fork+exec+waitpid的组合
 *              出错时：
 *                  当fork()出错时，返回-1
 *                  当waitpid()出错时并且errno！=EINTER时，返回-1
 *                  当exec出错时，相当于执行 exit(127)
 *              成功时，返回shell的终止状态，参看waitpid部分
 *  
 */
#include "apue.h"
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>

int system(const char *cmdstring) /* version without signal handling */
{
    pid_t pid;
    int status;

    if (cmdstring == NULL)
        return (1); /* always a command processor with UNIX */

    if ((pid = fork()) < 0) //fork()时，缓冲会被复制到子进程
    {
        status = -1; /* probably out of processes */
    }
    else if (pid == 0)
    { /* child */
        execl("/bin/bash", "bash", "-c", cmdstring, (char *)0);
        _exit(127); /* execl error */ //此处使用_exit()而不是exit(),是为了防止标准I/O缓冲在子进程中被冲洗。
    }
    else
    { /* parent */
        while (waitpid(pid, &status, 0) < 0)
        {
            if (errno != EINTR)
            {
                status = -1; /* error other than EINTR from waitpid() */
                break;
            }
        }
    }

    return (status);
}

int main(void)
{
    int status;

    if ((status = system("date")) < 0)
        err_sys("system() error");

    pr_exit(status);

    if ((status = system("nosuchcommand")) < 0)
        err_sys("system() error");

    pr_exit(status);

    if ((status = system("who; exit 44")) < 0)
        err_sys("system() error");

    pr_exit(status);

    exit(0);
}

/*

lwh@lwh-HP-Notebook:~/ProjsGit/apue/APUE_my/08_Process_Ctl$ ./system 
Tue 27 Jul 2021 11:59:19 AM CST
normal termination, exit status = 0

bash: nosuchcommand: command not found
normal termination, exit status = 127

lwh      tty7         2021-07-27 09:02 (:0)
normal termination, exit status = 4

*/